use serde_json::{Map, Value};
use shq_common::prelude::{dept::DeptmentCache, Callback};
use async_trait::async_trait;

pub struct OrganCallBack;
impl OrganCallBack {
    pub fn new() -> Self {
        OrganCallBack {}
    }
}
#[async_trait]
impl Callback for OrganCallBack {
    async fn before_insert(
        &mut self,
        map_val: Map<String, Value>,
        tx: &mut sqlx::Transaction<'_,sqlx::MySql>
    ) -> anyhow::Result<Map<String, Value>> {
        let no = map_val.get("no")
            .and_then(Value::as_str)
            .ok_or_else(|| anyhow::anyhow!("no字段没有找到"))?;
        if no.is_empty() {
            return Err(anyhow::anyhow!("no字段不能为空"));
        }
        let name=map_val.get("name")
            .and_then(Value::as_str)
            .ok_or_else(|| anyhow::anyhow!("name字段没有找到"))?;
        if name.is_empty() {
            return Err(anyhow::anyhow!("name字段不能为空"));
        }
        let sql= "SELECT COUNT(*) as count FROM sys_organization WHERE no = ?";
        let count: i64 = sqlx::query_scalar(sql)
            .bind(no)
            .fetch_one(&mut **tx)
            .await
            .map_err(|e| anyhow::anyhow!("查询no是否存在失败: {}", e))?;
        if  count > 0 {
            return Err(anyhow::anyhow!("部门编号:{no}已存在"));
        }
        let sql= "SELECT COUNT(*) as count FROM sys_organization WHERE name = ?";
        let count: i64 = sqlx::query_scalar(sql)
            .bind(no)
            .fetch_one(&mut **tx)
            .await
            .map_err(|e| anyhow::anyhow!("查询name是否存在失败: {}", e))?;
        if  count > 0 {
            return Err(anyhow::anyhow!("部门名称:{name}已存在"));
        }
        Ok(map_val)
    }
    async fn after_save(
        &mut self,
        map_val: Map<String, Value>,
        tx: &mut sqlx::Transaction<'_,sqlx::MySql>
    ) -> anyhow::Result<()> {
        // 更新缓存
        let mut dc=DeptmentCache::new()?;
        let id = map_val.get("id")
            .and_then(Value::as_u64)
            .ok_or_else(|| anyhow::anyhow!("id字段没有找到或不是u64类型"))?;
        dc.load_dept_by_id(id as u32,Some(tx))
            .await
            .map_err(|e| anyhow::anyhow!("加载部门缓存失败: {}", e))?;
        Ok(())
    }
    async fn after_delete(
        &mut self,
        ids: &[u64],
        _tx: &mut sqlx::Transaction<'_,sqlx::MySql>
    ) -> anyhow::Result<()> {
        // 更新缓存
        let mut dc=DeptmentCache::new()?;
        let ids: Vec<u32> = ids.iter().map(|&id| id as u32).collect();
        dc.del_dept_by_ids(&ids)
            .map_err(|e| anyhow::anyhow!("删除部门缓存失败: {}", e))?;
        Ok(())
    }
    async fn before_update(
        &mut self,
        map_val: Map<String, Value>,
        tx: &mut sqlx::Transaction<'_,sqlx::MySql>
    ) -> anyhow::Result<Map<String, Value>> {
        let id = map_val.get("id")
            .and_then(Value::as_i64)
            .ok_or_else(|| anyhow::anyhow!("id字段没有找到或不是u64类型"))?;
        let no = map_val.get("no")
            .and_then(Value::as_str)
            .ok_or_else(|| anyhow::anyhow!("no字段没有找到"))?;
        if no.is_empty() {
            return Err(anyhow::anyhow!("no字段不能为空"));
        }
        let name=map_val.get("name")
            .and_then(Value::as_str)
            .ok_or_else(|| anyhow::anyhow!("name字段没有找到"))?;
        if name.is_empty() {
            return Err(anyhow::anyhow!("name字段不能为空"));
        }
        let sql= "SELECT COUNT(*) as count FROM sys_organization WHERE no = ? AND id != ?";
        let count: i64 = sqlx::query_scalar(sql)
            .bind(no).bind(id)
            .fetch_one(&mut **tx)
            .await
            .map_err(|e| anyhow::anyhow!("查询no是否存在失败: {}", e))?;
        if  count > 0 {
            return Err(anyhow::anyhow!("部门编号:{no}已存在"));
        }
        let sql= "SELECT COUNT(*) as count FROM sys_organization WHERE name = ? AND id != ?";
        let count: i64 = sqlx::query_scalar(sql)
            .bind(no).bind(id)
            .fetch_one(&mut **tx)
            .await
            .map_err(|e| anyhow::anyhow!("查询name是否存在失败: {}", e))?;
        if  count > 0 {
            return Err(anyhow::anyhow!("部门名称:{name}已存在"));
        }
        Ok(map_val)
    }
    async fn after_find(
        &mut self,
        map_val: Map<String, Value>,
        _tx: &mut sqlx::Transaction<'_,sqlx::MySql>
    ) -> anyhow::Result<Map<String, Value>> {
        let pid = map_val.get("parent_id")
            .and_then(Value::as_u64)
            .ok_or_else(|| anyhow::anyhow!("parent_id字段没有找到或不是u64类型"))?;
        let mut map_val=map_val;
        if pid == 0 {
            map_val.entry("parent_id__dict").and_modify(|v|*v=Value::from("上海分行"));
        }
        // 如果缓存中没有，则返回原始数据
        Ok(map_val)
    }
}